package com.xinruke.hostels.systemmanage.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.xinruke.hostels.cache.extract.extractor.DictInfoCacheExtractor;
import com.xinruke.hostels.common.cache.ManageUserCache;
import com.xinruke.hostels.common.cache.vo.LoginManageResultVO;
import com.xinruke.hostels.common.constants.SysDicConstant;
import com.xinruke.hostels.common.exception.BizException;
import com.xinruke.hostels.common.mybatis.MyExample;
import com.xinruke.hostels.common.po.YewuyonghuCaozuoRizhi;
import com.xinruke.hostels.common.po.YwFangjian;
import com.xinruke.hostels.common.po.YwLouceng;
import com.xinruke.hostels.common.po.YwLoudong;
import com.xinruke.hostels.common.service.OperateLogService;
import com.xinruke.hostels.common.util.CollectionUtil;
import com.xinruke.hostels.common.vo.ErrorEnum;
import com.xinruke.hostels.common.vo.ResultVO;
import com.xinruke.hostels.common.vo.query.EConditionOperator;
import com.xinruke.hostels.common.vo.query.QueryConditions;
import com.xinruke.hostels.common.vo.query.RowsDataVO;
import com.xinruke.hostels.system.manage.interfaces.dto.*;
import com.xinruke.hostels.systemmanage.mapper.YwFangjianMapper;
import com.xinruke.hostels.systemmanage.mapper.YwLoucengMapper;
import com.xinruke.hostels.systemmanage.mapper.YwLoudongMapper;
import com.xinruke.hostels.systemmanage.service.RoomService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yutaipu
 */
@Service
@Slf4j
public class RoomServiceImpl implements RoomService {

    @Autowired
    private RoomTypeService roomTypeService;

    @Autowired
    private YwFangjianMapper ywFangjianMapper;

    @Autowired
    private YwLoudongMapper ywLoudongMapper;

    @Autowired
    private YwLoucengMapper ywLoucengMapper;

    @Autowired
    private DictInfoCacheExtractor dictInfoCacheExtractor;

    @Autowired
    private ManageUserCache manageUserCache;

    @Autowired
    OperateLogService operateLogService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO add(RoomAddDTO params) {
        ResultVO resultVO = ResultVO.success();

        RoomTypeDetailQueryResultDTO roomType = getRoomTypeById(params.getFangxingId());
        if (null == roomType) {
            return ResultVO.fail("没有对应的房型");
        }

        LoginManageResultVO userInfo = manageUserCache.getLoginManageUserInfo();

        YwFangjian add = new YwFangjian();
        BeanUtils.copyProperties(params, add);
        add.setJiudianId(userInfo.getJiudianId());
        add.setFangxingbianhao(roomType.getFangxingbianhao());
        add.setFangxingmingcheng(roomType.getFangxingmingcheng());
        add.setChuangjianrenId(userInfo.getId());
        add.setChuangjianshijian(new Date());
        add.setGengxinrenId(userInfo.getId());
        add.setGengxinshijian(new Date());
        add.setShanchubiaoshi(SysDicConstant.DELFLAG_0);
        add.setZhuangtai(SysDicConstant.ZHUANGTAI_YOU_XIAO);
        int count = ywFangjianMapper.insertSelective(add);
        if (count == 0) {
            return ResultVO.fail();
        }
        return resultVO;
    }

    private RoomTypeDetailQueryResultDTO getRoomTypeById(Integer fangjianleixingId) {
        RoomTypeDetailQueryDTO queryRoomTypeDto = new RoomTypeDetailQueryDTO();
        queryRoomTypeDto.setId(fangjianleixingId);
        return roomTypeService.getDetail(queryRoomTypeDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO modify(RoomModifyDTO params) {
        ResultVO resultVO = ResultVO.success();

        RoomTypeDetailQueryResultDTO roomType = getRoomTypeById(params.getFangxingId());
        if (null == roomType) {
            return ResultVO.fail("没有对应的房型");
        }

        YwFangjian modify = new YwFangjian();
        BeanUtils.copyProperties(params, modify);
        modify.setFangxingbianhao(roomType.getFangxingbianhao());
        modify.setFangxingmingcheng(roomType.getFangxingmingcheng());
        modify.setGengxinrenId(manageUserCache.getCurrentUserId());
        modify.setGengxinshijian(new Date());
        int count = ywFangjianMapper.updateByPrimaryKeySelective(modify);
        if (count == 0) {
            return ResultVO.fail();
        }
        return resultVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO delete(RoomDelQueryDTO delQueryDTO) {
        ResultVO resultVO = ResultVO.fail();

        int fangjianId = delQueryDTO.getId();

        //删除所有的房间
        YwFangjian fangjian = new YwFangjian();
        fangjian.setShanchubiaoshi(SysDicConstant.DELFLAG_1);
        fangjian.setGengxinrenId(manageUserCache.getCurrentUserId());
        fangjian.setGengxinshijian(new Date());

        QueryConditions fangjianQueryCondition = new QueryConditions();
        fangjianQueryCondition.addCondition("id", EConditionOperator.EQULS, fangjianId);
        fangjianQueryCondition.addCondition("jiudianId", EConditionOperator.EQULS, manageUserCache.getJiudianId());
        MyExample fangjianMyExample = new MyExample(YwFangjian.class, fangjianQueryCondition);
        int fangjianRet = ywFangjianMapper.updateByExampleSelective(fangjian, fangjianMyExample);
        if (fangjianRet <= 0) {
            log.error("删除房间失败，房间id[" + fangjianId + "]");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

            resultVO.setMessage("删除房间失败");
            return resultVO;
        }

        //写入操作日志
        YewuyonghuCaozuoRizhi yewuyonghuCaozuoRizhi = new YewuyonghuCaozuoRizhi("房间", "删除房间", "房间id[" + fangjianId + "]");
        operateLogService.writeOperateLog(yewuyonghuCaozuoRizhi);

        resultVO = ResultVO.success();

        return resultVO;
    }

    @Override
    public RowsDataVO<RoomQueryResultDTO> getRoomList(RoomQueryDTO params) {
        RowsDataVO<RoomQueryResultDTO> dataVO = new RowsDataVO<>();
        QueryConditions conditions = new QueryConditions();

        conditions.addCondition("shanchubiaoshi", EConditionOperator.EQULS, SysDicConstant.DELFLAG_0);
        conditions.addCondition("jiudianId", EConditionOperator.EQULS, manageUserCache.getJiudianId());
        if (null != params.getLoudongId() && params.getLoudongId().intValue() > 0) {
            conditions.addCondition("loudongId", EConditionOperator.EQULS, params.getLoudongId());
        }
        if (null != params.getLoucengId() && params.getLoudongId().intValue() > 0) {
            conditions.addCondition("loucengId", EConditionOperator.EQULS, params.getLoucengId());
        }
        if (null != params.getFangxingId() && params.getLoudongId().intValue() > 0) {
            conditions.addCondition("fangxingId", EConditionOperator.EQULS, params.getFangxingId());
        }
        if (StringUtils.isNotBlank(params.getFangjianbianhao())) {
            conditions.addCondition("fangjianbianhao", EConditionOperator.LIKE, params.getFangjianbianhao());
        }

        MyExample example = new MyExample(YwFangjian.class, conditions, params.getOrderFields());
        Page<YwFangjian> page = PageHelper.startPage(params.getPageNo(), params.getPageSize());
        List<YwFangjian> list = ywFangjianMapper.selectByExample(example);
        List<RoomQueryResultDTO> resultList = Lists.newArrayList();
        if (!CollectionUtil.isEmpty(list)) {
            resultList = list.stream().map(n -> {
                RoomQueryResultDTO dto = new RoomQueryResultDTO();
                BeanUtils.copyProperties(n, dto);
                YwLouceng louceng = new YwLouceng();
                louceng.setId(n.getLoucengId());
                louceng = ywLoucengMapper.selectByPrimaryKey(louceng);
                if (louceng != null) {
                    dto.setLoucengMingcheng(louceng.getMingcheng());
                }
                dto.setZhuangtaiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHUANGTAI, dto.getZhuangtai()));
                dto.setChaoxiangMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.CHAOXIANG, dto.getChaoxiang()));

                RoomTypeDetailQueryResultDTO roomType = getRoomTypeById(dto.getFangxingId());
                dto.setChaoyudingshu(roomType.getChaoyudingshu());
                dto.setYajin(roomType.getYajin());
                return dto;
            }).collect(Collectors.toList());
        }
        dataVO.setPageNo(page.getPageNum());
        dataVO.setTotalRecords(page.getTotal());
        dataVO.setTotalPages(page.getPages());
        dataVO.setRows(resultList);
        return dataVO;
    }

    @Override
    public RoomDetailQueryResultDTO getDetail(RoomDetailQueryDTO detailQueryDTO) {

        YwFangjian ywHuichang = ywFangjianMapper.selectByPrimaryKey(detailQueryDTO.getId());

        RoomDetailQueryResultDTO dto = new RoomDetailQueryResultDTO();
        BeanUtils.copyProperties(ywHuichang, dto);
        dto.setZhuangtaiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHUANGTAI, dto.getZhuangtai()));
        dto.setChaoxiangMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.CHAOXIANG, dto.getChaoxiang()));
        RoomTypeDetailQueryResultDTO roomType = getRoomTypeById(dto.getFangxingId());
        dto.setChaoyudingshu(roomType.getChaoyudingshu());
        dto.setYajin(roomType.getYajin());
        return dto;
    }

    @Override
    public Integer count(RoomCountQueryDTO params) {
        if (null == params.getJiudianId()) {
            throw new BizException(ErrorEnum.ERROR_26001.getCode(), ErrorEnum.ERROR_26001.getMsg());
        }
        return ywFangjianMapper.countByJiudianIdOrTypeId(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<Integer> addBatch(RoomAddBatchDTO params) {
        ResultVO resultVO = ResultVO.success();
        YwLoudong loudong = ywLoudongMapper.selectByPrimaryKey(params.getLoudongId());
        if (loudong == null) {
            return ResultVO.fail("没有对应的楼栋信息");
        }
        YwLouceng louceng = ywLoucengMapper.selectByPrimaryKey(params.getLoucengId());
        if (louceng == null) {
            return ResultVO.fail("没有对应的楼层信息");
        }
        RoomTypeDetailQueryResultDTO roomType = getRoomTypeById(params.getFangxingId());
        if (null == roomType) {
            return ResultVO.fail("没有对应的房型信息");
        }
        RoomAddDTO addDto = new RoomAddDTO();
        BeanUtils.copyProperties(params, addDto);

        int fenjihaomaIndex = params.getFenjihaomakaishi();
        for (int i = params.getFangjianbianhaokaishi(); i <= params.getFangjianbianhaojieshu(); i++) {
            addDto.setFangjianbianhao(params.getFangjianbianhaoqianzhui() + i);
            if (fenjihaomaIndex <= params.getFenjihaomajieshu()) {
                addDto.setFenjihaoma(params.getFenjihaomaqianzhui() + fenjihaomaIndex++);
            } else {
                addDto.setFenjihaoma("无");
            }
            resultVO = add(addDto);
            if (resultVO.getCode() == ResultVO.FAIL) {
                throw new BizException(ErrorEnum.ERROR_50000);
            }
        }
        return resultVO;
    }

    @Override
    public List<RoomCountByFangxingResultDTO> countByFangxing(Integer loucengId) {
        return ywFangjianMapper.countByFangxing(loucengId);
    }

    @Override
    public RowsDataVO<RoomUnusedQueryResultDTO> getRoomUnusedList(RoomUnusedQueryDTO roomUnusedQueryDTO) {
        RowsDataVO<RoomUnusedQueryResultDTO> rowsDataVO = new RowsDataVO<RoomUnusedQueryResultDTO>();

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("jiudianid", manageUserCache.getJiudianId());
        paramMap.put("kaishishijian", roomUnusedQueryDTO.getKaishishijian());
        paramMap.put("jieshushijian", roomUnusedQueryDTO.getJieshushijian());
        if (roomUnusedQueryDTO.getLoudongId() != null) {
            paramMap.put("loudongid", roomUnusedQueryDTO.getLoudongId());
        }
        if (roomUnusedQueryDTO.getLoucengId() != null) {
            paramMap.put("loucengid", roomUnusedQueryDTO.getLoucengId());
        }
        if (roomUnusedQueryDTO.getFangxingId() != null) {
            paramMap.put("fangxingid", roomUnusedQueryDTO.getFangxingId());
        }
        if (roomUnusedQueryDTO.getFangjianzhuangtai() != null) {
            paramMap.put("fangjianzhuangtai", roomUnusedQueryDTO.getFangjianzhuangtai());
        }


        Page<RoomUnusedQueryResultDTO> page = PageHelper.startPage(roomUnusedQueryDTO.getPageNo(), roomUnusedQueryDTO.getPageSize());
        List<RoomUnusedQueryResultDTO> roomUnusedQueryResultDTOList = ywFangjianMapper.getRoomUnusedList(paramMap);

        rowsDataVO.setRows(roomUnusedQueryResultDTOList);
        rowsDataVO.setPageNo(page.getPageNum());
        rowsDataVO.setTotalPages(page.getTotal());
        rowsDataVO.setTotalRecords(page.getPages());

        return rowsDataVO;
    }

}
